﻿using MyHelper;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Media3D;
using System.Windows.Shapes;
using HandyControl.Controls;
using System.Security;
using clf.weighing.entity;
using Material = clf.weighing.entity.Material;
using TextBox = System.Windows.Controls.TextBox;
using CheckBox = System.Windows.Controls.CheckBox;
using Binding = System.Windows.Data.Binding;
using Brushes = System.Windows.Media.Brushes;
using Color = System.Windows.Media.Color;
using System.Collections.ObjectModel;




namespace weighing
{
    /// <summary>
    /// ReportWindow.xaml 的交互逻辑
    /// </summary>
    public partial class ReportWindow : GlowWindow
    {
        #region variabes      
        private ObservableCollection<WeighingBillVo>? mWeihingBillVos = new ObservableCollection<WeighingBillVo>();
        private static string unitText = App.Config.WeighingConfig.Unit == Unit.Tone ? "吨" : "千克";
        private string InDetailTotalStatisticLabelTemplate = "合计: ({0}) 家公司供应({1}) 种物资，共({2})车，原发净重:{3}（" + unitText + "） 收货毛重:{4}（" + unitText + "） 收货皮重: {5}（" + unitText + "）收货净重: {6}（" + unitText + "）扣重:{7} (" + unitText + ") 磅差:{8}(" + unitText + ")";
        private string OutDetailTotalStatisticLabelTemplate = "合计: 供应 ({0}) 家公司({1}) 种物资，共({2})车，发货皮重: {3}（" + unitText + "） 发货毛重:{4}（" + unitText + "） 发货净重: {5}";
        private string mixtureDetailTotalStatisticLabelTemplate = "合计: ({0}) 种物资，共({1})车， 毛重:{2}（" + unitText + "）皮重: {3}（" + unitText + "） 净重: {4}";
        private string ListBoxItemLabelTemplate = " 公司名称：{0}  物资名称：{1}  {2}(车)  毛重：{3}  皮重： {4}  净重：{5} (" + unitText + ")";

        private List<ReportWeightListV>? ReportWeightListVs;
        #endregion

        #region property
        public WeightingBillType BillType
        {
            get { return (WeightingBillType)GetValue(BillTypeProperty); }
            set { SetValue(BillTypeProperty, value); }
        }
        public static readonly DependencyProperty BillTypeProperty =
            DependencyProperty.Register("BillType", typeof(WeightingBillType), typeof(ReportWindow), new PropertyMetadata(WeightingBillType.UNKNOWN));

        #endregion


        public ReportWindow()
        {
            InitializeComponent();
            CommonFunction.ShowCustomIcon(this);
        }

        #region Window Event
        private void Report_In_Window_Loaded(object sender, RoutedEventArgs e)
        {
            this.Data_Grid.ItemsSource = mWeihingBillVos;

            InitHeader();
            //根据类型显示或隐藏列
            HandleColumnShowOrHide();
            //根据配制显示或隐藏列
            ShowOrHideColumns();

            DynamicSetSearchTextBox();

            DynamicSetBackField();

            InitStartDate();

            SetDefaultSource();
        }

        private void Window_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
        {
            switch (e.Key)
            {
                case Key.Escape:
                    if (this.statisticPopup.IsOpen == true)
                    {
                        this.statisticPopup.IsOpen = false;
                    }
                    else
                    {
                        this.Close();
                    }
                    break;
                default:
                    break;
            }
        }

        #endregion

        private void InitStartDate()
        {
            var now = DateTime.Now;
            DateTime select = new DateTime(now.Year, now.Month, now.Day, 0, 0, 1);
            this.startDateTime.SelectedDateTime = select;
            this.endDateTime.SelectedDateTime = new DateTime(now.Year, now.Month, now.Day, 23, 59, 59); ;
        }

        private void InitHeader()
        {
            this.PrintTimeTb.Text = DateTimeHelper.getCurrentDateTime();
            this.exclHelder.Text = App.CurrentCompanyVo.FullName;
            this.exclSubHeader.Text = GetSubHeader();
            this.Title = this.exclSubHeader.Text;
        }

        /// <summary>
        /// 将本机使用的基础数据设置默认数据源 
        /// </summary>
        private void SetDefaultSource()
        {
            var companyS = CompanyDao.Instance.GetList().Select(i => { return new CompanyVo(i); }).ToList();
            var ms = MaterialDao.Instance.GetList().Select(i => { return new MaterialVo(i); }).ToList();
            var cars = CarDao.Instance.GetList().Select(i => { return new CarInfoVo(i); }).ToList();
            this.sendCompanyCb.ItemsSource = companyS;
            this.RecevieCompanyCb.ItemsSource = companyS;
            this.materialCb.ItemsSource = ms;
            this.carNumberCb.ItemsSource = cars;
        }

        private string GetSubHeader()
        {
            string res = "";
            switch (BillType)
            {
                case WeightingBillType.Buy:
                    res = "采购入库过磅数据报表";
                    break;
                case WeightingBillType.Sale:
                    res = "销售出库过磅数据报表";
                    break;
                case WeightingBillType.Self:
                    res = "内部倒运过磅数据报表";
                    break;
                case WeightingBillType.Foreign:
                    res = "外来过磅数据报表";
                    break;
                case WeightingBillType.Mixture:
                    res = "过磅数据报表";
                    break;
            }
            return res;
        }

        private void HandleColumnShowOrHide()
        {
            ShowOrHidePriceColumn();
            switch (BillType)
            {
                case WeightingBillType.Buy:
                    this.DiffWeightColumn.Visibility = Visibility.Visible;
                    this.DecuationDescColumn.Visibility = Visibility.Visible;
                    this.DecuationDescColumn.Visibility = Visibility.Visible;
                    break;
                case WeightingBillType.Sale:
                case WeightingBillType.Self:
                case WeightingBillType.Foreign:
                    this.DiffWeightColumn.Visibility = Visibility.Collapsed;
                    this.DecuationDescColumn.Visibility = Visibility.Collapsed;
                    this.DecuationDescColumn.Visibility = Visibility.Collapsed;
                    if (BillType != WeightingBillType.Sale)
                    {
                        if (BillType == WeightingBillType.Self)
                        {
                            if (CommonFunction.HasPermision(PermissionKeys.BillClearSelf))
                            {
                                this.ClearBtn.Visibility = Visibility.Visible;
                            }
                            else
                            {
                                this.ClearBtn.Visibility = Visibility.Collapsed;
                            }

                        }
                        else if (BillType == WeightingBillType.Foreign)
                        {
                            if (CommonFunction.HasPermision(PermissionKeys.BillClearForeign))
                            {
                                this.ClearBtn.Visibility = Visibility.Visible;
                            }
                            else
                            {
                                this.ClearBtn.Visibility = Visibility.Collapsed;
                            }
                        }
                    }
                    break;
            }

        }

        /// <summary>
        /// 动态设置备用字段的列
        /// </summary>
        private void DynamicSetBackField()
        {
            int type = (int)this.BillType;

            List<BackupBillField> fields = BackupBillFieldDao.Instance.SelectAllByType(type);

            if (fields == null || fields.Count == 0) return;

            for (int i = 0; i < fields.Count; i++)
            {
                BackupBillField item = fields[i];
                if (item.isEnable == 1 && item.isShow == 1)
                {
                    DataGridTextColumn column = new DataGridTextColumn
                    {
                        Header = item.displayName,
                        Binding = new Binding(StringHelper.DBNamingToCamelCase(item.fiedName, true)),
                    };
                    int index = this.Data_Grid.Columns.Count - 1;
                    this.Data_Grid.Columns.Insert(index, column);
                }
            }

        }

        /// <summary>
        /// 动态设置搜索文本框
        /// </summary>
        private void DynamicSetSearchTextBox()
        {
            this.searchPanel.Children.Clear();

            int type = (int)this.BillType;
            List<BackupBillField> fields = BackupBillFieldDao.Instance.SelectAllByType(type);
            if (fields == null || fields.Count == 0) return;
            foreach (var item in fields)
            {
                if (item.isEnable == 1 && item.isSearch == 1)
                {
                    int w = item.width < 200 ? 200 : item.width;
                    w = item.width > 400 ? 400 : item.width;
                    TextBox textBox = new TextBox()
                    {
                        Name = item.fiedName + "TB",
                        Style = FindResource("TextBoxExtend") as Style,
                        Margin = new Thickness(5, 2, 5, 2),
                        MinWidth = 100,
                        MaxWidth = 400,
                        Width = w,
                        ToolTip = $"备用字段：{item.displayName}"
                    };
                    InfoElement.SetTitle(textBox, item.displayName);
                    InfoElement.SetTitlePlacement(textBox, HandyControl.Data.TitlePlacementType.Left);
                    InfoElement.SetTitleWidth(textBox, new GridLength(Convert.ToDouble(item.titleWidth)));
                    this.searchPanel.Children.Add(textBox);
                }
            }

        }
        private void ShowOrHidePriceColumn()
        {

            this.PriceColumn.Visibility = Visibility.Collapsed;
            this.TotalColumn.Visibility = Visibility.Collapsed;
            this.ReceiveMoneyColumn.Visibility = Visibility.Collapsed;
            this.MoneyTypeColumn.Visibility = Visibility.Collapsed;

            switch (BillType)
            {
                case WeightingBillType.Sale:
                    if (App.Config.BillPrintConfig.OutShowCalculate)
                    {
                        this.PriceColumn.Visibility = Visibility.Visible;
                        this.TotalColumn.Visibility = Visibility.Visible;
                        this.ReceiveMoneyColumn.Visibility = Visibility.Visible;
                        this.MoneyTypeColumn.Visibility = Visibility.Visible;
                    }
                    break;
                case WeightingBillType.Buy:
                    if (App.Config.BillPrintConfig.InShowCalculate)
                    {
                        this.PriceColumn.Visibility = Visibility.Visible;
                        this.TotalColumn.Visibility = Visibility.Visible;
                        this.ReceiveMoneyColumn.Visibility = Visibility.Visible;
                        this.MoneyTypeColumn.Visibility = Visibility.Visible;
                    }
                    break;

            }
        }


        private void Report_Window_ContentRendered(object sender, EventArgs e)
        {
            LoadData();
        }
        /// <summary>
        /// 设置报表的时间区间
        /// </summary>
        private void SetDateRange()
        {
            var strart = GetStartDate();
            if (strart.IsNullOrEmpty())
            {
                strart = "未知";
            }
            var end = GetEndDate();
            if (end.IsNullOrEmpty())
            {
                end = "今天";
            }
            this.dateRangeTb.Text = strart + "-" + end;
        }

        #region DataGrid
        private void DataGrid_LoadingRow(object sender, DataGridRowEventArgs e)
        {
            e.Row.Header = e.Row.GetIndex() + 1;

            if (e.Row.DataContext is WeighingBillVo bill)
            {
                if (bill.Status == 0)
                {
                    e.Row.Foreground = Brushes.Red;
                }
                else
                {
                    e.Row.Foreground = new SolidColorBrush(Color.FromRgb(66, 66, 66));
                }
                if (bill.UpGovernmentStatus == 1)
                {
                    e.Row.Foreground = Brushes.LightGreen;
                }
                else if (bill.UpGovernmentStatus == 2)
                {
                    e.Row.Foreground = Brushes.Green;
                }
            }

        }

        private void DataGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e)
        {
            //WeighingBillVo bill = this.Data_Grid.SelectedItem as WeighingBillVo;
            //new picwe(bill).ShowDialog();
        }
        private void Data_Grid_LostFocus(object sender, RoutedEventArgs e)
        {
            //this.Data_Grid.SelectedItem = null;
        }
        #endregion

        /// <summary>
        /// 加载数据
        /// </summary>
        public void LoadData()
        {
            mWeihingBillVos?.Clear();
            string backFieldCondition = GetBackFieldCondition();
            var list = WeighingBillDao.Instance.GetReportBills(BillType, GetStartDate(), GetEndDate(), GetSendCompanyName(), GetReceiveCompanyName(), GetMateriaName(), GetPlate(), backFieldCondition);
            list?.ForEach(i => { mWeihingBillVos?.Add(new WeighingBillVo(i)); });
            SetDateRange();
            GetStatisticData();
            SummmaryStatisticData();
            string msg = $"共查询到:{mWeihingBillVos?.Count()} 条数据，单次的最大查询条数为:" + Constant.ReportMaxRows;
            Growl.Info(msg);
        }

        /// <summary>
        /// 获取备用字段作为 查询条件
        /// </summary>
        /// <returns></returns>
        private string GetBackFieldCondition()
        {
            if (this.searchPanel.Children.Count == 0) return "";

            string condition = "";

            foreach (var item in this.searchPanel.Children)
            {
                if (item is TextBox textBox)
                {
                    string name = textBox.Name.Replace("TB", "");
                    string value = textBox.Text;
                    if (string.IsNullOrEmpty(value))
                    {
                        continue;
                    }
                    if (name.Contains("_string"))
                    {
                        if (string.IsNullOrEmpty(condition))
                        {
                            condition = $"`{name}` like '%{value}%'";
                        }
                        else
                        {
                            condition = $" and `{name}` like '%{value}%'";
                        }
                    }
                    else
                    {
                        if (string.IsNullOrEmpty(condition))
                        {
                            condition = $"`{name}` = {value}";
                        }
                        else
                        {
                            condition = $" and `{name}` = {value}";
                        }
                    }
                }
            }

            if (string.IsNullOrEmpty(condition))
            {
                return "";
            }
            else
            {
                if (condition.StartsWith(" and"))
                {
                    condition = condition.Substring(4);
                }
                return "(" + condition + ")";
            }
        }


        /// <summary>
        /// 获取统计数据
        /// </summary>
        private void GetStatisticData()
        {

            this.statisticListBox.Text = string.Empty;
            if (BillType == WeightingBillType.ExitSlip
                || BillType == WeightingBillType.Otrher
                || BillType == WeightingBillType.UNKNOWN)
            {
                return;
            }
            var backFieldCondition = GetBackFieldCondition();
            ReportWeightListVs = WeighingBillDao.Instance.GetListStatisticData(BillType, GetStartDate(), GetEndDate(), GetSendCompanyName(), GetReceiveCompanyName(), GetMateriaName(), GetPlate(),backFieldCondition);
            var sb = new StringBuilder();
            foreach (ReportWeightListV v in ReportWeightListVs)
            {
                string text = String.Format(this.ListBoxItemLabelTemplate, v.Company, v.Material, v.Cars, v.GrossWeight, v.TraeWeight, v.Weight);
                sb.AppendLine(text);
            }
            this.statisticListBox.Text = sb.ToString();
        }

        private void SummmaryStatisticData()
        {
            this.summaryTextBox.Text = "";
            if (BillType == WeightingBillType.ExitSlip
                || BillType == WeightingBillType.Otrher
                || BillType == WeightingBillType.UNKNOWN)
            {
                return;
            }
            var backFieldCondition = GetBackFieldCondition();
            ReportWeightSummaryV v = WeighingBillDao.Instance.GetReportWeightSummaryData(BillType, GetStartDate(), GetEndDate(), GetSendCompanyName(), GetReceiveCompanyName(), GetMateriaName(), GetPlate(), backFieldCondition);
            if (v != null)
            {
                //InDetailTotalStatisticLabelTemplate 统计差异
                switch (BillType)
                {
                    case WeightingBillType.Otrher:
                        break;
                    case WeightingBillType.Buy:
                        this.summaryTextBox.Text = String.Format(this.InDetailTotalStatisticLabelTemplate, v.Companys, v.Materials, v.Cars.ToString(), v.SendWeight, v.GrossWeight, v.TraeWeight, v.NetWeight, v.DecuationWeight, v.DiffWeight);
                        break;
                    case WeightingBillType.Sale:
                        this.summaryTextBox.Text = String.Format(this.OutDetailTotalStatisticLabelTemplate, v.Companys, v.Materials, v.Cars.ToString(), v.TraeWeight, v.GrossWeight, v.NetWeight);
                        break;
                    case WeightingBillType.Self:
                        this.summaryTextBox.Text = String.Format(this.OutDetailTotalStatisticLabelTemplate, v.Companys, v.Materials, v.Cars.ToString(), v.TraeWeight, v.GrossWeight, v.NetWeight);
                        break;
                    case WeightingBillType.Foreign:
                        this.summaryTextBox.Text = String.Format(this.OutDetailTotalStatisticLabelTemplate, v.Companys, v.Materials, v.Cars.ToString(), v.TraeWeight, v.GrossWeight, v.NetWeight);
                        break;
                    case WeightingBillType.Mixture:
                        this.summaryTextBox.Text = String.Format(this.mixtureDetailTotalStatisticLabelTemplate, v.Materials, v.Cars.ToString(), v.GrossWeight, v.TraeWeight, v.NetWeight);
                        break;
                    case WeightingBillType.UNKNOWN:
                        break;
                    case WeightingBillType.ExitSlip:
                        break;
                }

            }
        }

        #region build search condition
        private string GetSendCompanyName()
        {
            CompanyVo sendVo = this.sendCompanyCb.SelectedItem as CompanyVo;
            if (sendVo != null)
            {
                return sendVo.FullName;
            }
            return this.sendCompanyCb.Text;
        }
        private string GetReceiveCompanyName()
        {
            CompanyVo sendVo = this.RecevieCompanyCb.SelectedItem as CompanyVo;
            if (sendVo != null)
            {
                return sendVo.FullName;
            }
            return this.RecevieCompanyCb.Text;
        }
        private string GetMateriaName()
        {
            MaterialVo materialVo = this.materialCb.SelectedItem as MaterialVo;
            if (materialVo != null)
            {
                return materialVo.Name;
            }
            return this.materialCb.Text;
        }
        private string GetPlate()
        {
            CarInfoVo carInfo = carNumberCb.SelectedItem as CarInfoVo;
            if (carInfo != null)
            {
                return carInfo.CarNumber;
            }
            return carNumberCb.Text;
        }
        #endregion

        private string GetStartDate()
        {
            if (startDateTime.SelectedDateTime == null)
            {
                return null;
            }
            DateTime tempdate = (DateTime)startDateTime.SelectedDateTime;
            if (tempdate == null)
            {
                return null;
            }
            return tempdate.ToString("yyyy-MM-dd HH:mm:ss");
        }

        private string GetEndDate()
        {
            var tempdate = endDateTime.SelectedDateTime;
            return tempdate?.ToString("yyyy-MM-dd HH:mm:ss") ?? "";

        }

        #region Supply 
        private bool isSupplySelected = false;
        private void SupplyCb_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (BillType == WeightingBillType.Buy)
            {
                //In Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.InNecessarySend == false) return;
            }
            else
            {
                //Out Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.OutNecessarySend == false) return;
            }

            String text = this.sendCompanyCb.Text.Trim();
            if (text.Length < 2)
            {
                isSupplySelected = false;
                this.sendCompanyCb.IsDropDownOpen = false;
            }
            if (isSupplySelected == true) { return; }
            if (text.Length >= 2)
            {
                List<Company> list = CompanyDao.Instance.SelectByNameOrFirstCaseLike(text);
                var data = list?.Select((i) => { return new CompanyVo(i); }).ToList();
                isSupplySelected = list?.Count <= 0;
                this.sendCompanyCb.ItemsSource = data;
                this.sendCompanyCb.IsDropDownOpen = sendCompanyCb.ItemsSource != null;
            }
        }
        private void SupplyCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (sendCompanyCb.SelectedIndex > -1) isSupplySelected = true;
        }

        #endregion

        #region Receiver Company
        private bool isSelectReceiveCompany = false;
        private void ReceiverCompanyCb_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (BillType == WeightingBillType.Buy)
            {
                //In Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.InNecessaryReceive == false) return;
            }
            else
            {
                //Out Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.OutNecessaryReceive == false) return;
            }

            String text = this.RecevieCompanyCb.Text.Trim();
            if (text.Length < 2)
            {
                isSelectReceiveCompany = false;
                this.RecevieCompanyCb.IsDropDownOpen = false;
            }
            if (isSelectReceiveCompany == true) { return; }
            if (text.Length >= 2)
            {
                List<Company> list = CompanyDao.Instance.SelectByNameOrFirstCaseLike(text);
                var data = list?.Select((i) => { return new CompanyVo(i); }).ToList();
                isSelectReceiveCompany = list?.Count > 0;
                this.RecevieCompanyCb.IsDropDownOpen = this.RecevieCompanyCb.ItemsSource != null;
                this.RecevieCompanyCb.ItemsSource = data;
            }
        }
        private void ReceiverCompanyCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (RecevieCompanyCb.SelectedIndex > -1) isSelectReceiveCompany = true;
        }
        #endregion

        #region Material 
        private bool isSelectMaterial = false;
        private void MaterialNameCb_TextChanged(object sender, TextChangedEventArgs e)
        {
            if (BillType == WeightingBillType.Buy)
            {
                //In Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.InNecessaryMaterial == false) return;
            }
            else
            {
                //Out Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.OutNecessaryMaterial == false) return;
            }

            String text = this.materialCb.Text.Trim();
            if (text.Length < 2)
            {
                isSelectMaterial = false;
                this.materialCb.IsDropDownOpen = false;
            }
            if (isSelectMaterial == true) { return; }
            if (text.Length >= 2)
            {
                List<Material> list = MaterialDao.Instance.SelectByNameOrFirstCaseLike(text);
                var data = list?.Select((i) => { return new MaterialVo(i); }).ToList();
                isSelectMaterial = list?.Count > 0;
                this.materialCb.ItemsSource = data;
                this.materialCb.IsDropDownOpen = this.materialCb.ItemsSource != null;
            }
        }

        private void MaterialNameCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (materialCb.SelectedIndex > -1) isSelectMaterial = true;
        }
        #endregion

        #region CarInfo Selection
        private bool isCarInfoSelectioned = false;
        private void CarNumberCb_TextChanged(object sender, TextChangedEventArgs e)
        {
            String text = this.carNumberCb.Text.Trim();
            if (text.Length <= 0)
            {
                isCarInfoSelectioned = false;
                this.carNumberCb.IsDropDownOpen = false;
                return;
            }
            if (BillType == WeightingBillType.Buy)
            {
                //In Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.InNecessaryCar == false) return;
            }
            else
            {
                //Out Necessary Send  not must ,not to search
                if (App.Config.WeighingConfig.OutNecessaryCar == false) return;
            }

            if (isCarInfoSelectioned == true) { return; }

            if (text.Length >= 2)
            {
                List<CarInfo> list = CarDao.Instance.SelectByLike(text);
                var data = list?.Select((i) => { return new CarInfoVo(i); }).ToList();
                this.carNumberCb.ItemsSource = data;
                this.carNumberCb.IsDropDownOpen = carNumberCb.ItemsSource != null;
            }
        }

        private void CarNumberCb_SelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            if (carNumberCb.SelectedIndex > -1) isCarInfoSelectioned = true;
        }
        #endregion

        #region 动态显示列

        private Dictionary<Int32, CheckBox> columnsDics;
        private void ColumnsSettingBtn_Click(object sender, RoutedEventArgs e)
        {
            if (columnsDics == null)
            {
                columnsDics = new Dictionary<int, CheckBox>();
                var cols = this.Data_Grid.Columns;
                var style = FindResource("CheckBoxBaseStyle") as Style;
                for (int i = 0; i < cols.Count; i++)
                {
                    var col = cols[i];
                    var cb = new CheckBox()
                    {
                        Style = style,
                        Content = col.Header,
                        HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
                        Tag = i,
                        Margin = new Thickness(20, 5, 20, 5),
                    };
                    if (col.Visibility == Visibility)
                    {
                        cb.IsChecked = true;
                    }
                    else
                    {
                        cb.IsChecked = false;
                    }
                    cb.Checked += ColumnCheckBox_Checked;
                    cb.Unchecked += ColumnCheckBox_Unchecked;
                    columnsDics.Add(i, cb);
                }
                foreach (var item in columnsDics)
                {
                    this.columnsPanel.Children.Add(item.Value);
                }
            }
            this.columnPopup.IsOpen = !columnPopup.IsOpen;
        }
        private void ColumnCheckBox_Checked(object sender, RoutedEventArgs e)
        {
            if (sender is CheckBox cb)
            {
                var index = (int)cb.Tag;
                var col = this.Data_Grid.Columns[index];
                if (col != null)
                {
                    col.Visibility = Visibility.Visible;
                    string header = cb?.Content?.ToString() ?? "";
                    if (!header.IsNullOrEmpty())
                    {
                        SaveColumnSetting(header, false);
                    }
                }
            }
        }

        private void ColumnCheckBox_Unchecked(object sender, RoutedEventArgs e)
        {
            if (sender is CheckBox cb)
            {
                var index = (int)cb.Tag;
                var col = this.Data_Grid.Columns[index];
                if (col != null)
                {
                    col.Visibility = Visibility.Collapsed;
                    string header = cb?.Content?.ToString() ?? "";
                    if (!header.IsNullOrEmpty())
                    {
                        SaveColumnSetting(header, false);
                    }
                }
            }
        }

        #endregion

        //查询
        private void StartSeatchBtn_Click(object sender, RoutedEventArgs e)
        {
            LoadData();
        }

       

        /// <summary>
        /// 打印选中
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void PrintBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.Data_Grid.SelectedItem is WeighingBillVo bill)
            {
                if (App.Config.BillPrintConfig.IsUserExclCustomBill)
                {
                    new PrintEXCLWindow(bill.Id)
                    {
                        Owner = App.Current.MainWindow
                    }.ShowDialog();
                }
                else
                {
                    new PrintWindow(bill.Id, WeightingBillType.WeighintBill)
                    {
                        Owner = App.Current.MainWindow
                    }.ShowDialog();
                }     
            }
            else
            {
                Growl.Info("你还没有选择任何数据！");
            }
        }

        private void DeleteBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.Data_Grid.SelectedItem is WeighingBillVo bill)
            {
                string msg = $"是否要删除编号为 {bill.Number} 的过磅数据？";
                var result = CommonFunction.Ask(msg, this);

                if (result == MessageBoxResult.Yes)
                {
                    this.DeleteReasonPopup.Tag = bill.Number; //将 编号 进行传递
                    this.DeleteReasonPopup.IsOpen = true;
                }
            }
            else
            {
                Growl.Info("你还没有选择要删除的数据！");
            }
        }

        #region popup delete reason  弹窗删除
        private void PopupCancelBtn_Click(object sender, RoutedEventArgs e)
        {
            this.DeleteReasonPopup.IsOpen = false;
        }

        private void PopupDeleteBtn_Click(object sender, RoutedEventArgs e)
        {
            string reason = this.DeleteReasonCb.Text.Trim();
            if (reason.Length < 5)
            {
                CommonFunction.AlertInfo("请选择或者输入删除该数据的原因，5个字以上");
                return;
            }
            this.DeleteReasonPopup.IsOpen = false;
            string number = this.DeleteReasonPopup?.Tag?.ToString() ?? "";
            if (string.IsNullOrEmpty(number))
            {
                Growl.Info("删除失败！", "main");
                return;
            }
            bool res = WeighingBillDao.Instance.SoftDelete(number, reason);
            if (res)
            {
                LoadData();
                Growl.Success($"{number} 删除成功", "main");

                Log.Info($"{number} 被 {App.CurrentUser?.name} 删除成功");
            }
            else
            {
                Growl.Error($"{number} 删除失败", "main");
            }
        }
        private void DeleteReasonPopup_Closed(object sender, EventArgs e)
        {
            this.DeleteReasonCb.SelectedIndex = -1;
            this.DeleteReasonCb.Text = "";
        }

        #endregion


        //清空数据
        private void ClearBtn_Click(object sender, RoutedEventArgs e)
        {
            string msg = $"是否要清空 {this.GetSubHeader().Replace("报表", "")} ";
            var result = CommonFunction.Ask(msg);
            if (result == MessageBoxResult.Yes)
            {
                int res = WeighingBillDao.Instance.SoftDeleteBytype(BillType);
                if (res > 0)
                {
                    Growl.Success("清除成功！");

                    LoadData();

                    RecordClearLog();
                }
                else
                {
                    Growl.Error("清除失败！");
                }
            }
        }

        private async void RecordClearLog()
        {
            string header = this.GetSubHeader().Replace("报表", "");
            await Task.Factory.StartNew(() =>
              {
                  var msg = $"{App.CurrentUser?.name} 在 {DateTime.Now.ToString(Constant.DateTimeFormat)} 清空了{header}。";
                  Log.Error(msg);
              });
        }

        private void EditBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.Data_Grid.SelectedItem is WeighingBillVo vo)
            {
                //Bill  Edit Window
                if(App.Config.WeighingConfig.WeighingMode == WeighingMode.Simple)
                {
                    new BillEditSimpleWindow(vo)
                    {
                        Owner = App.Current.MainWindow,
                    }.ShowDialog();
                }
                else
                {
                    new BillEditWindow(vo)
                    {
                        Owner = App.Current.MainWindow,
                        OnChanged = (res) => { if (res) LoadData(); }
                    }.ShowDialog();
                }                
            }
            else
            {
                Growl.Info("你还没有选择要修改的数据！");
            }
        }

        #region show image

        /// <summary>
        /// 查看详情
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void DetailBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.Data_Grid.SelectedItem is WeighingBillVo vo)
            {
                OpenDetail(vo);
            }
            else
            {
                Growl.Info("你还没有选择任何数据！");
            }
        }

        private void OpenDetail(WeighingBillVo vo)
        {
            this.DrawerHeaderTb.Text = vo.Number + " 磅单截图详情";
            this.detailRootBorder.Content = null;
            StackPanel panel = new StackPanel();
            //var inprint = new InPrint() { DataContext = mWeighingBillVo };
            //panel.Children.Add(inprint);
            var img = new BillImageUC(vo.mWeighingBill);
            panel.Children.Add(img);
            this.detailRootBorder.Content = panel;
            this.DrawerBottom.IsOpen = true;
        }


        #endregion


        #region 列显示配制

        protected void ShowOrHideColumns()
        {
            var dg = this.Data_Grid;
            string name = GetColumnsName();

            var dic = DataGridColumnsHelper.GetByName(name);

            var columns = dg.Columns;

            if (dic.Count == 0)
            {
                foreach (var c in columns)
                {
                    if (c is DataGridTextColumn tc)
                    {
                        string header = tc.Header.ToString();
                        if (dic.Keys.Contains(header))
                        {
                            dic[header] = true;
                        }
                        else
                        {
                            dic.Add(header, true);
                        }
                    }
                }

                DataGridColumnsHelper.Save(name, dic);
            }
            else
            {
                foreach (var c in columns)
                {
                    if (c is DataGridTextColumn tc)
                    {
                        string header = tc.Header.ToString();
                        if (dic.Keys.Contains(header))
                        {
                            if (dic[header] == true)
                            {
                                tc.Visibility = Visibility.Visible;
                            }
                            else
                            {
                                tc.Visibility = Visibility.Collapsed;
                            }
                        }
                        else
                        {
                            tc.Visibility = Visibility.Collapsed;
                        }
                    }
                }
            }
        }


        protected void SaveColumnSetting(string header, bool isShow)
        {
            string name = GetColumnsName();

            DataGridColumnsHelper.Save(name, header, isShow);
        }

        private string GetColumnsName()
        {
            string res = "";
            switch (BillType)
            {
                case WeightingBillType.Buy:
                    res = DataGridColumnsHelper.reportBuy;
                    break;
                case WeightingBillType.Sale:
                    res = DataGridColumnsHelper.reportSale;
                    break;
                case WeightingBillType.Self:
                    res = DataGridColumnsHelper.reportSelf;
                    break;
                case WeightingBillType.Foreign:
                    res = DataGridColumnsHelper.reportforegin;
                    break;
                case WeightingBillType.Mixture:
                    res = DataGridColumnsHelper.mixture;
                    break;
            }
            return res;
        }
        #endregion

        #region 弹窗显示 popup show statistic list info

        private void StatisticPopup_Opened(object sender, EventArgs e)
        {
            var lb = this.statisticListBox;
            this.list_parnel.Children.Clear();
            this.popupStackPanel.Children.Clear();
            this.popupStackPanel.Children.Add(lb);
        }

        private void StatisticPopup_Closed(object sender, EventArgs e)
        {
            var lb = this.popupStackPanel.Children[0];
            this.popupStackPanel.Children.Clear();
            this.list_parnel.Children.Clear();
            this.list_parnel.Children.Add(lb);
        }

        private ReportPopupWin reportPopupWin = null;

        //弹窗显示
        private void PopupShowBtn_Click(object sender, RoutedEventArgs e)
        {
            if (this.ReportWeightListVs.Count > 0)
            {
                if (reportPopupWin == null)
                {
                    var t = this.summaryTextBox.Text;
                    reportPopupWin = new ReportPopupWin(this.ReportWeightListVs, t);
                    reportPopupWin.ShowDialog();
                    reportPopupWin = null;
                }
                else
                {
                    reportPopupWin.Close();
                    reportPopupWin = null;
                }
            }
            else
            {
                Growl.Clear();
                Growl.Info("没有可查看的统计数据");
            }

        }
        #endregion

        #region 导入 下载导入模板 导出
        /// <summary>
        /// 是否正在导入
        /// </summary>
        private bool isImporting = false;

        /// <summary>
        /// 导入
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void ImportBtn_Click(object sender, RoutedEventArgs e)
        {
            if (isImporting == false)
            {
                isImporting = true;
                string fileName = "";
                //弹出保存对话框,并保存文件
                var ofd = new Microsoft.Win32.OpenFileDialog
                {
                    DefaultExt = ".xlsx",
                    Filter = "EXCL Files (*.xlsx,*.xls)|*.xlsx|JSON Files (*.json)|*.json|All files (*.*)|*.*"

                };
                if (ofd.ShowDialog() == true)
                {
                    if (ofd.FileName != "")
                    {
                        fileName = ofd.FileName;  //将其进行保存到指定的路径                                                   
                    }
                }
                if (!FileHelper.Exists(fileName))
                {
                    Growl.Clear();
                    Growl.Error("未选择需要导入的文件");
                    isImporting = false;
                    return;
                }

                if (!(fileName.EndsWith(".xlsx")
                    || fileName.EndsWith(".xls")
                    || fileName.EndsWith(".json")))
                {
                    Growl.Clear();
                    Growl.Error("导入的文件只能是*.xlsx、*.xls、*.json");
                    isImporting = false;
                    return;
                }

                if (fileName.EndsWith(".json"))
                {
                    ImportFromJson(fileName);
                }
                else
                {
                    ImportFromExcl(fileName);
                }

                isImporting = false;
            }
        }

        private void ImportFromExcl(string fileName)
        {
            var headers = GetHeaderDic();
            var res = ExclHelper.Import(4, headers, fileName);
            Growl.Clear();
            if (res.Count > 0)
            {
                Growl.Info("开发中。。。");
                return;
                Growl.Success($"成功读取 {res.Count} 条数据，进行异步保存，请留意桌面的导入日志");
                Growl.Success(TimeInfo(res.Count));
                var task = SaveImportDataAsync(res);
                Console.WriteLine("先输出");
                task.ContinueWith((t) =>
                {
                    if (t.IsCompleted)
                    {
                        Growl.Success("导入结束");
                        this.Dispatcher.Invoke(() => { LoadData(); });
                    }
                    else if (t.IsFaulted)
                    {
                        Growl.Clear();
                        Growl.Info("导入结束,有错：" + t.Exception?.InnerException?.Message ?? "");
                    }
                    else { }
                });
            }
            else
            {
                Growl.Info("导入 0 条数据");
            }
        }


        private void ImportFromJson(string fileName)
        {
            string json = FileHelper.Reader(fileName, Encoding.UTF8);
            if (!CommonFunction.IsJsonContent(json))
            {
                Growl.Clear();
                Growl.Info("文件内容为空或不符合");
                return;
            }
            Growl.Clear();

            var datas = JsonHelper.JsonToObject<List<WeighingBill>>(json);

            if (datas == null || datas.Count == 0)
            {
                Growl.Info("导入 0 条数据");
                return;
            }

            if (datas.Count > 0)
            {
                Growl.Success($"成功读取 {datas.Count} 条数据，进行异步保存，请留意桌面的导入日志");
                Growl.Success(TimeInfo(datas.Count));
                var task = SaveImportDataJsonAsync(datas);

                task.ContinueWith((t) =>
                {
                    if (t.IsCompleted)
                    {
                        Growl.Success("导入结束");
                        this.Dispatcher.Invoke(() => { LoadData(); });
                    }
                    else if (t.IsFaulted)
                    {
                        Growl.Clear();
                        Growl.Info("导入结束,有错：" + t.Exception?.InnerException?.Message ?? "");
                    }
                    else { }
                });
            }
            else
            {
                Growl.Info("导入 0 条数据");
            }
        }

        /// <summary>
        /// 时间提示
        /// </summary>
        /// <param name="counts"></param>
        /// <returns></returns>
        private string TimeInfo(long counts)
        {
            string res = "每秒大概10条，大概需要 ";
            string u = "秒钟";
            long t = counts / 10;
            if(counts > 1000) {
                u = "分钟";
                t = counts / 10 / 60;
            }
            return res + t + u;
        }


        private async Task<bool> SaveImportDataJsonAsync(List<WeighingBill> bills)
        {
            return await Task<bool>.Run(() =>
            {
                int succCount = 0;
                int failCount = 0;
                string title = "磅单数据JSON导入";
                string time = DateTimeHelper.getCurrentDateTime();
                var msg = "=================================================================\r\n ";
                msg += $"{time} {title}，有 {bills.Count} 条数据要处理\r\n";
                Console.WriteLine(msg);
                for (int i = 0; i < bills.Count; i++)
                {
                    var bill = bills[i];
                    try
                    {
                        var tempBill = WeighingBillDao.Instance.FindByNumber(bill.number);
                        //单号存在，不导入
                        if (tempBill != null)
                        {
                            msg += $"\r\n {i + 1} \t {bill.number} 导入失败 已经存在";
                            failCount++;
                            continue;
                        }

                        var idc = WeighingBillDao.Instance.FindById(bill.id);
                        if (idc != null)
                        {
                            if (tempBill == null)
                            {
                                bill.id = IdHelper.LongID;
                            }
                            else
                            {
                                msg += $"\r\n {i + 1} \t {bill.number} 导入失败 已经存在";
                                failCount++;
                                continue;
                            }
                        }

                        // save data to databases;
                        bill.isDelete ??= 0;
                        bill.affiliatedCompanyId = App.initConfig?.companyId ?? 0;
                        int res = CarDao.Instance.Sqlite.Insert(bill);
                        if (res > 0)
                        {
                            succCount++;
                            msg += $"\r\n {i + 1} \t {bill.number} 导入成功";
                        }
                        else
                        {
                            msg += $"\r\n {i + 1} \t {bill.number} 导入失败";
                            failCount++;
                        }
                    }
                    catch (Exception ex)
                    {

                        msg += $"\r\n导入{bill.number} 出错:{ex.Message} --- \r\n";
                    }
                }

                msg += $" \r\n{time} 处理完成,成功 {succCount} 失败：{failCount} 。\r\n ";
                msg += "=================================================================\r\n";
                Console.WriteLine("处理完成");
                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                var d = DateTimeHelper.getCurrentDateTime(DateTimeHelper.DateFormat);
                string file = System.IO.Path.Combine(desktopPath, d + $"_{title}日志.txt");
                FileHelper.WriteAppend(file, msg);
                return true;
            });

        }

        /// <summary>
        /// TODO 保存磅单数据
        /// </summary>
        /// <param name="result">磅单数据</param>
        /// <returns></returns>
        private async Task<bool> SaveImportDataAsync(List<String> result)
        {
            //注意类型的匹配
            return await Task<bool>.Run(() =>
            {
                int succCount = 0;
                int failCount = 0;
                string title = "磅单数据导入";
                string time = DateTimeHelper.getCurrentDateTime();
                var msg = "=================================================================\r\n ";
                msg += $"{time} {title}，有 {result.Count} 条数据要处理\r\n";
                Console.WriteLine(msg);
                var bills = new List<WeighingBill>();
                for (int i = 0; i < result.Count; i++)
                {
                    string json = result[i];
                    var dic = JsonHelper.JsonToObject<Dictionary<string, string>>(json);
                    var nDic = new Dictionary<string, string>();

                    foreach (var item in dic)
                    {
                        string key = StringHelper.LowerCaseFirstLetter(item.Key);
                        var sub = "Text";//后辍
                        if (key.EndsWith(sub))
                        {
                            string value = item.Value == "是" ? "1" : "0";
                            nDic.Add(key.Substring(0, key.Length - sub.Length), value);
                        }
                        else
                        {
                            if (nDic.ContainsKey(key))
                            {
                                nDic[key] = item.Value;
                            }
                            else
                            {
                                nDic.Add(key, item.Value);
                            }
                        }
                    }
                    var billjson = JsonHelper.ObjectToJson(nDic);
                    Console.WriteLine("new json:" + json);

                    var bill = JsonHelper.JsonToObject<WeighingBill>(billjson);
                    if (bill == null)
                    {
                        msg += $" \r\n {billjson} \t 表格数据不能被转化成有效的磅单数据数据";
                    }
                    else
                    {
                        bill.isDelete = 0;
                        bill.id = IdHelper.LongID;
                        bill.addUserId = 0;
                        if (string.IsNullOrEmpty(bill.addUserName)) bill.addUserName = "";
                        bill.driverMobile = bill.driverMobile.Replace(" ", "");
                        if (bill.addTime == null) bill.addTime = DateTime.Now;
                        bills.Add(bill);
                    }
                }

                //开始处理数据
                for (int i = 0; i < bills.Count; i++)
                {
                    var bill = bills[i];
                
                    //判断是否存在 
                    if (WeighingBillDao.Instance.FindByNumber(bill.number) != null )
                    {
                        msg += $"\r\n {i + 1} \t {bill.carNumber} 导入失败 已经存在";
                        failCount++;
                        continue;
                    }
                    bill.id += i;
                    // save data to databases;
                    int res = WeighingBillDao.Instance.Sqlite.Insert(bill);
                    if (res > 0)
                    {
                        succCount++;
                        msg += $"\r\n {i + 1} \t {bill.carNumber} 导入成功";
                    }
                    else
                    {
                        msg += $"\r\n {i + 1} \t {bill.carNumber} 导入失败";
                        failCount++;
                    }
                }
                msg += $" \r\n{time} 处理完成,成功 {succCount} 失败：{failCount} 。\r\n ";
                msg += "=================================================================\r\n";
                Console.WriteLine("处理完成");
                string desktopPath = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
                var d = DateTimeHelper.getCurrentDateTime(DateTimeHelper.DateFormat);
                string file = System.IO.Path.Combine(desktopPath, d + $"_{title}日志.txt");
                FileHelper.WriteAppend(file, msg);
                return true;
            });

        }

        /// <summary>
        /// 下载导入模板
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void TemplateBtn_Click(object sender, RoutedEventArgs e)
        {
            if (isExporting == false)
            {
                isExporting = true;
                string title = "磅单数据导入模板";
                string filename = title;
                string subtitle = "导入模板";
                Dictionary<string, string> headers = GetHeaderDic();

                var res = ExclHelper.DownTemplate(headers, filename, title, subtitle);

                Growl.Clear();
                if (res)
                {
                    Growl.Success("下载成功");
                }
                else
                {
                    Growl.Error("模板下载失败");
                }
                isExporting = false;
            }
        }

        private Dictionary<string, string> GetHeaderDic()
        {
            var headerDic = new Dictionary<string, string>();
            foreach (var column in this.Data_Grid.Columns)
            {
                if (column is DataGridTextColumn textColumn)
                {
                    var binding = textColumn.Binding as System.Windows.Data.Binding;
                    var key = binding?.Path.Path ?? "";
                    var val = textColumn.Header.ToString();
                    headerDic.Add(key, val ?? "");
                }
            }
            return headerDic;
        }

        #region 导出
        private bool isExporting = false;

        private void ExportBtn_Click(object sender, RoutedEventArgs e)
        {
            if (isExporting == false)
            {
                isExporting = true;
                var start = DateTime.Now;
                Console.WriteLine("开始导出：" + start.ToString(Constant.DateTimeFormat));
                Growl.Clear();
                Growl.Info("导出中请等待。");
                var headerDic = CommonFunction. GetHeaderDic(this.Data_Grid,true);
                var datas = mWeihingBillVos?.Select(vo => CommonFunction.ObjectToDict(vo, true, true)).ToList();
                var text = CommonFunction.GetWeighungTypeText(BillType);
                string filename = DateTimeHelper.getCurrentDateTime(DateTimeHelper.DateFormat) + text + "明细";
                string title = App.CurrentCompanyVo?.FullName?? "";
                string time = this.dateRangeTb.Text + "     导出时间:" + DateTimeHelper.getCurrentDateTime();
                string subtitle = GetSubHeader();
                var result = ExclHelper.ExclExprotToExcel(datas, headerDic, filename, title, subtitle, time, this.summaryTextBox.Text, GetListStatisticString());
                if (result > 0)
                {
                    var diff = DateTime.Now - start;
                    var m = Math.Floor(diff.TotalSeconds / 60);
                    var s = Math.Floor(diff.TotalSeconds % 60);
                    var msg = $"结束导出：共{mWeihingBillVos?.Count??0} 条数据，用时：{m}分{s} 秒";
                    Console.WriteLine(msg);
                    Growl.Clear();
                    Growl.Success(msg);
                }
                else
                {
                    Growl.Clear();
                    Growl.Info("导出失败");
                }
                isExporting = false;
            }
        }

        private List<string>? GetListStatisticString()
        {
            var list = this.statisticListBox.Text.Split(new string[] { "\r\n" }, StringSplitOptions.None);
            return list?.ToList();
        }

        private List<String>? GetListStatisticToListString(System.Windows.Controls.ListBox listBox)
        {
            if (listBox == null || listBox.Items.Count <= 0)
            {
                return null;
            }
            List<string> list = new List<string>();

            for (int i = 0; i < listBox.Items.Count; i++)
            {
                TextBlock tb = (TextBlock)listBox.Items[i];
                if (tb != null)
                {
                    list.Add(tb.Text);
                }
                else
                {
                    list.Add(" ");
                }
            }
            return list;
        }
        #endregion

        #endregion

    }
}